#include "stdafx.h"

HINSTANCE Application::hInst;
Wnd* Application::pWndMain = 0;
WndPointerTable Application::PWNDTable;
Document Application::currentDoc;

/* Settings */
TCHAR ApplicationSetting::szTitle[MAX_LOADSTRING];
bool ApplicationSetting::ShowGridLine = true;
bool ApplicationSetting::ShowHeader = true;
float ApplicationSetting::Zooming  = 1.0;

/******************************
 * Application Initializing Entrance
 ***/
BOOL Application::Init(HINSTANCE hInstance, int nCmdShow)
{	
	// Initialize the basic settings
	::LoadString(hInstance, IDS_APP_TITLE, ApplicationSetting::szTitle, MAX_LOADSTRING);
	
	// Initialize the Main Window
	if (!InitWndMain (hInstance, nCmdShow))
	{
		return FALSE;
	}
	return TRUE;
}

/******************************
 * Initialize the WndMain
 ***/
BOOL Application::InitWndMain(HINSTANCE hInstance, int nCmdShow)
{
	hInst = hInstance; // Store instance handle of the Application

	pWndMain = new WndMain(ApplicationSetting::szTitle, WS_OVERLAPPEDWINDOW /*| WS_HSCROLL | WS_VSCROLL*/);
	if (!pWndMain->hWnd)
	{
		return FALSE;
	}

	/* Register pWndMain in WndPointerTable
		 so that application can get the message mapping
		 and redirect the message sending. */
	RegisterPWnd(pWndMain, pWndMain->hWnd);

	pWndMain->ShowWindow(nCmdShow);
	pWndMain->UpdateWindow();

	return TRUE;
}

/*****************************
 * Register in WindowPointerTable
 *		to establish matching between pWnd with hWnd
 ***/
void Application::RegisterPWnd(Wnd* PWnd, HWND HWnd)
{
	WndPointerItem wpItem(PWnd, HWnd);
	PWNDTable.Add(wpItem);
}

/**********************************
 * Main Message Loop
 ***/
int Application::Run()
{
	// TODO: Place code here.

	MSG msg;
	HACCEL hAccelTable;
	hAccelTable = ::LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_ACCELERATOR1));

	// Main message loop:
	while (::GetMessage(&msg, NULL, 0, 0))
	{
		if (msg.hwnd != WndGridCtlr::GetEditBoxHwnd())
		{
			if (!::TranslateAccelerator(pWndMain->hWnd, hAccelTable, &msg))
			{
				::TranslateMessage(&msg);
				::DispatchMessage(&msg);
			}
		}
		else
		{
			::TranslateMessage(&msg);
			::DispatchMessage(&msg);
		}
	}
	return (int) msg.wParam;
}

/******************************
 * Release Resources
 ***/
void Application::End()
{
	delete pWndMain;
}

/******************************
* Main WndProc that receive all messages
***/
LRESULT CALLBACK Application::AppWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
	// Before the main window is created, Windows OS process the message
	if(pWndMain == 0)
		return ::DefWindowProc(hWnd, nMsg, wParam, lParam);

	// According to hWnd find the pWnd, and redirect the message sending.
	Wnd* pWndTarget = PWNDTable.Find(hWnd);
	if (pWndTarget == 0)
	{
		return ::DefWindowProc(hWnd, nMsg, wParam, lParam);
	}
	// Re-send messages
	return InnerWndProc(pWndTarget, hWnd, nMsg, wParam, lParam);
}

/******************************
* Sending messages to virtual Wnd->WndProc
* then messages are sent to corresponding Window Controller
***/
LRESULT CALLBACK Application::InnerWndProc(Wnd*pWnd, HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
	return pWnd->WndProc(hWnd, nMsg, wParam, lParam);
}
